#ifndef NC_SAVER_H
#define NC_SAVER_H

#include "FDataStreamBase.h"
#include "zlib.h"

class NCSaver : public FDataStreamBase
{
public:
	NCSaver(FDataStreamBase* pOrigStream);
	~NCSaver();
	virtual void Release();
	virtual void Start(FDataStreamBase* pOrigStream);

	virtual void	Rewind();
	virtual bool	AtEnd();
	virtual void	FastFwd();
	virtual unsigned int  GetPosition() const;
	virtual void    SetPosition(unsigned int position);
	virtual void    Truncate();
	virtual void	Flush();
	virtual unsigned int	GetEOF() const;
	virtual unsigned int			GetSizeLeft() const;
	virtual void	CopyToMem(void* mem);
	
	virtual unsigned int	ReadString(char *szName);
	virtual unsigned int	ReadString(wchar *szName);
	virtual unsigned int	ReadString(std::string& szName);
	virtual unsigned int	ReadString(std::wstring& szName);
	virtual unsigned int	ReadString(int count, std::string values[]);
	virtual unsigned int	ReadString(int count, std::wstring values[]);
	
	virtual char *			ReadString();		// allocates memory 
	virtual wchar *		ReadWideString();	// allocates memory 

	virtual unsigned int	WriteString(const wchar *szName);
	virtual unsigned int	WriteString(const char *szName);
	virtual unsigned int	WriteString(const std::string& szName);
	virtual unsigned int	WriteString(const std::wstring& szName);
	virtual unsigned int	WriteString(int count, std::string values[]);
	virtual unsigned int	WriteString(int count, std::wstring values[]);
	

	virtual void		Read( char *);			//
	virtual void		Read(byte *);
	virtual void		Read(int count, char values[]);
	virtual void		Read(int count, byte values[]);
	virtual void		Read(bool *);
	virtual void		Read(int count, bool values[]);
	virtual void		Read(short	*s);
	virtual void		Read(unsigned short	*s);
	virtual void		Read(int count, short values[]);
	virtual void		Read(int count, unsigned short values[]);
	virtual void		Read(int* i);
	virtual void		Read(unsigned int* i);
	virtual void 		Read(int count, int values[]);
	virtual void 		Read(int count, unsigned int values[]);

	virtual void		Read(long* l);
	virtual void		Read(unsigned long* l);
	virtual void 		Read(int count, long values[]);
	virtual void 		Read(int count, unsigned long values[]);

	virtual void		Read(float* value);
	virtual void		Read(int count, float values[]);

	virtual void		Read(double* value);
	virtual void		Read(int count, double values[]);

	virtual void		Write( char value);			//
	virtual void		Write(byte value);
	virtual void		Write(int count, const  char values[]);
	virtual void		Write(int count, const  byte values[]);

	virtual void		Write(bool value);			//
	virtual void		Write(int count, const bool values[]);

	virtual void		Write(short value);			//
	virtual void		Write(unsigned short value);
	virtual void		Write(int count, const short values[]);	//
	virtual void		Write(int count, const unsigned short values[]);

	virtual void		Write(int value);			//
	virtual void		Write(unsigned int value);
	virtual void 		Write(int count, const int values[]);	//
	virtual void		Write(int count, const unsigned int values[]);

	virtual void		Write(long value);
	virtual void		Write(unsigned long  value);
	virtual void 		Write(int count, const long values[]);
	virtual void		Write(int count, const unsigned long values[]);

	virtual void		Write(float value);
	virtual void		Write(int count, const float values[]);

	virtual void		Write(double value);
	virtual void		Write(int count, const double values[]);

private:
	FDataStreamBase* m_pMainStream;
	FILE* m_fStream ;
	char* m_szPathName;
	byte* m_pbInBuf;
	byte* m_pbOutBuf;

	z_stream m_zStrm;

	int m_iBufNdx;
	int m_iZlibStatus;
	int m_iBufEnd;

	fpos_t m_lStartPos;

	bool m_bIsWriting;
	bool m_bHasFile;
	bool m_bStarted;

	void makeFileName();
	void open(bool bWrite);
	void close();
	void write(const void *buffer, size_t size, int count);
	void read(void *buffer, size_t size, int count);
	void Deflate();
	void Inflate();
	void report();
	void init();
	void uninit(bool bFinal);


};
#endif
